package com.anolesoft.twelvePlan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.anolesoft.twelvePlan.dto.*;
import com.anolesoft.twelvePlan.entity.MesPlanGradeDO;
import com.anolesoft.twelvePlan.entity.MesPlanXiaDaDO;
import com.anolesoft.twelvePlan.mapper.*;
import com.anolesoft.twelvePlan.service.PlanCheckService;
import com.anolesoft.twelvePlan.vo.MesOrderTraceTiaoMaVO;
import com.anolesoft.twelvePlan.vo.StfEmployeeToChargeVO;
import com.anolesoft.yr.util.CommonUtils;
import com.anolesoft.yr.util.PageData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zyq
 * @date 2022/3/25
 */
@Service
@Slf4j
public class PlanCheckServiceImpl implements PlanCheckService {

    @Autowired
    private MesPlanXiaDaMapper mesPlanXiaDaMapper;
    @Autowired
    private StfEmployeeToChargeMapper stfEmployeeToChargeMapper;
    @Autowired
    private MesGyInfoMapper mesGyInfoMapper;
    @Autowired
    private MesPlanGradeMapper mesPlanGradeMapper;
    @Autowired
    private MesPlanXiadaFuzerenMapper mesPlanXiadaFuzerenMapper;
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    public List<MesPlanXiadaJixingDTO> selectJx(PlanCheckDTO planCheckDTO) {
        return this.mesPlanXiaDaMapper.selectJx(planCheckDTO);
    }

    @Override
    public PageData<List<PlanCheckDTO>> queryCheck(PlanCheckDTO planCheckDTO, Integer pageNo, Integer pageSize) {
        int total;
        List<PlanCheckDTO> result;
        if (StrUtil.isEmptyOrUndefined(planCheckDTO.getParentpartid())) {
            Page<PlanCheckDTO> page = new Page<>(pageNo, pageSize);
            result = this.mesPlanXiaDaMapper.queryCheck(planCheckDTO, page);
            total = (int)page.getTotal();
        } else {
            List<PlanCheckDTO> root = this.mesPlanXiaDaMapper.queryForParentpartid(planCheckDTO, true);
            List<PlanCheckDTO> tree = new ArrayList<>();
            for (PlanCheckDTO p:root) {
                List<PlanCheckDTO> leaves = this.mesPlanXiaDaMapper.queryForParentpartid(PlanCheckDTO.builder()
                        .jx(CommonUtils.stringNull(p.getJx()))
                        .serialnumber(CommonUtils.stringNull(p.getSerialnumber()))
                        .checkTime2Date(planCheckDTO.getCheckTime2Date())
                        .factoryId(planCheckDTO.getFactoryId())
                        .build(),false);
                for (PlanCheckDTO leaf:leaves) {
                    tree.add(leaf);
                }
            }
            total = tree.size();
            int min = (pageNo - 1) * pageSize;
            int max = pageNo * pageSize;
            if (total < max) {
                result = tree.subList(min,total);
            } else {
                result = tree.subList(min,max);
            }
        }
        return new PageData<>(total, result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateCheck(PlanCheckDTO planCheckDTO) {
        String planGrade = CommonUtils.stringNull(planCheckDTO.getPlangrade());
        log.debug("计划等级：" + planGrade);
        if (!StrUtil.isEmptyOrUndefined(planGrade)) {
            if (!planGrade.equals("noChange")) {
                MesPlanGradeDO mesPlanGradeDO = this.mesPlanGradeMapper.queryGradeName(planGrade);
                planCheckDTO.setPlangradeid(planGrade);
                planCheckDTO.setPlangrade(mesPlanGradeDO.getPlanGrade());
            }
        } else {
            planCheckDTO.setPlangradeid("");
            planCheckDTO.setPlangrade("");
        }
        String mesPlanXiadaUid = CommonUtils.stringNull(planCheckDTO.getObjuid());
        List<MesPlanXiadaFuzerenDTO> fuzerenDTOS = this.mesPlanXiadaFuzerenMapper.queryFuzeren(mesPlanXiadaUid);
        this.mesPlanXiadaFuzerenMapper.deleteFuzeren(mesPlanXiadaUid);
        String[] names = planCheckDTO.getChargePersonList();
        for (int i = 0; i < names.length; i++) {
            String stfEmployeeUid = names[i];
            if (!stfEmployeeUid.matches("^[a-z0-9A-Z]+$")) {
                for (MesPlanXiadaFuzerenDTO fuzeren : fuzerenDTOS) {
                    if (fuzeren.getName().equals(stfEmployeeUid)) {
                        stfEmployeeUid = fuzeren.getObjuid();
                        break;
                    }
                }
            }
            log.debug("计划下达表主键：" + mesPlanXiadaUid + "人员表主键：" + stfEmployeeUid);
            this.mesPlanXiadaFuzerenMapper.insertFuzeren(mesPlanXiadaUid, stfEmployeeUid);
        }
        //String waixie = CommonUtils.stringNull(planCheckDTO.getWaixie());
        //if (!StrUtil.isEmptyOrUndefined(waixie) && waixie.equals("空")) {
        //    MesPlanGradeDO mesPlanGradeDO = this.mesPlanGradeMapper.queryGradeName(planGrade);
        //    planCheckDTO.setPlangradeid(planGrade);
        //    planCheckDTO.setPlangrade(mesPlanGradeDO.getPlanGrade());
        //}
        int count = this.mesPlanXiaDaMapper.updateCheck(PlanCheckDTO.builder()
                .objuid(CommonUtils.stringNull(planCheckDTO.getObjuid()))
                .jx(CommonUtils.stringNull(planCheckDTO.getJx()))
                .partid(CommonUtils.stringNull(planCheckDTO.getPartid()))
                .djnum(planCheckDTO.getDjnum())
                .innerwork(CommonUtils.stringNull(planCheckDTO.getInnerwork()))
                .processroute(CommonUtils.stringNull(planCheckDTO.getProcessroute()))
                .longperiodpart(CommonUtils.stringNull(planCheckDTO.getLongperiodpart()))
                .deliverytype(CommonUtils.stringNull(planCheckDTO.getDeliverytype()))
                .parttype(CommonUtils.stringNull(planCheckDTO.getParttype()))
                .jsworkshop(CommonUtils.stringNull(planCheckDTO.getJsworkshop()))
                .jfworkshop(CommonUtils.stringNull(planCheckDTO.getJfworkshop()))
                .deliveryorder(CommonUtils.stringNull(planCheckDTO.getDeliveryorder()))
                .matching(CommonUtils.stringNull(planCheckDTO.getMatching()))
                .groupingA(CommonUtils.stringNull(planCheckDTO.getGroupingA()))
                .isexecutable(CommonUtils.stringNull(planCheckDTO.getIsexecutable()))
                .delivertotal(CommonUtils.stringNull(planCheckDTO.getDelivertotal()))
                .deliverstate(CommonUtils.stringNull(planCheckDTO.getDeliverstate()))
                .outprocess(CommonUtils.stringNull(planCheckDTO.getOutprocess()))
                .waixie(CommonUtils.stringNull(planCheckDTO.getWaixie()))
                .waixiefactory(CommonUtils.stringNull(planCheckDTO.getWaixiefactory()))
                .remarks1(CommonUtils.stringNull(planCheckDTO.getRemarks1()))
                .moreinfo(CommonUtils.stringNull(planCheckDTO.getMoreinfo()))
                .endproduct(CommonUtils.stringNull(planCheckDTO.getEndproduct()))
                .tools(CommonUtils.stringNull(planCheckDTO.getTools()))
                .equipment(CommonUtils.stringNull(planCheckDTO.getEquipment()))
                .technicalquality(CommonUtils.stringNull(planCheckDTO.getTechnicalquality()))
                .blanking(CommonUtils.stringNull(planCheckDTO.getBlanking()))
                .outsourcing(CommonUtils.stringNull(planCheckDTO.getOutsourcing()))
                .outcooperation(CommonUtils.stringNull(planCheckDTO.getOutcooperation()))
                .ladong(CommonUtils.stringNull(planCheckDTO.getLadong()))
                .plangrade(CommonUtils.stringNull(planCheckDTO.getPlangrade()))
                .issue(planCheckDTO.getIssue())
                .mesprogress(CommonUtils.stringNull(planCheckDTO.getMesprogress()))
                .state(CommonUtils.stringNull(planCheckDTO.getState()))
                .affectedstation(CommonUtils.stringNull(planCheckDTO.getAffectedstation()))
                .chargeperson(CommonUtils.stringNull(planCheckDTO.getChargeperson()))
                //.checktime(planCheckDTO.getChecktime())
                .actualtime(planCheckDTO.getActualtime())
                .ladongchecktime(planCheckDTO.getLadongchecktime())
                .delivertime(planCheckDTO.getDelivertime())
                .completiontime(planCheckDTO.getCompletiontime())
                .checkTime2Date(planCheckDTO.getCheckTime2Date())
                .jxmlstock(planCheckDTO.getJxmlstock())
                .mlstocktotal(planCheckDTO.getMlstocktotal())
                .bcpstocknum(planCheckDTO.getBcpstocknum())
                .bcpstocktotal(planCheckDTO.getBcpstocktotal())
                .tempplannum(planCheckDTO.getTempplannum())
                .jxmltotal(planCheckDTO.getJxmltotal())
                .jxbcptotal(planCheckDTO.getJxbcptotal())
                .productstock(planCheckDTO.getProductstock())
                .gdchecktime(planCheckDTO.getGdchecktime())
                .plangradeid(CommonUtils.stringNull(planCheckDTO.getPlangradeid()))
                .plantime(planCheckDTO.getPlantime())
                .build());
        return count;
    }

    @Override
    public int checkPlan(String[] objuids, String checksUid) {
        int count = 0;
        for (String s: objuids) {
            this.mesPlanXiaDaMapper.checkPlan(s, checksUid);
            count++;
        }
        return count;
    }

    @Override
    public List<StfEmployeeToChargeVO> chargePerson(String factoryId) {
        return this.stfEmployeeToChargeMapper.chargePerson(factoryId);
    }

    @Override
    public List<MesPlanGradeDTO> planGrade(String factoryId) {
        List<MesPlanGradeDO> mesPlanGradeDOS = this.mesPlanGradeMapper.queryForCheck(factoryId);
        List<MesPlanGradeDTO> mesPlanGradeDTOS = mesPlanGradeDOS.stream()
                .map(t -> BeanUtil.copyProperties(t, MesPlanGradeDTO.class))
                .collect(Collectors.toList());
        return mesPlanGradeDTOS;
    }

    @Override
    public String selectBlanking(String objuid) {
        return this.mesGyInfoMapper.selectBlanking(objuid);
    }

    @Override
    public String selectOutsourcing(String objuid) {
        return this.mesGyInfoMapper.selectOutsourcing(objuid);
    }

    @Override
    public PageData<List<PlanCheckExport>> exportCheck(PlanCheckDTO planCheckDTO, Integer pageNo, Integer pageSize) {
        int total;
        List<PlanCheckExport> result;
        Page<PlanCheckExport> page = new Page<>(pageNo, pageSize);
        if (StrUtil.isEmptyOrUndefined(planCheckDTO.getParentpartid())) {
            result = this.mesPlanXiaDaMapper.exportCheck(planCheckDTO, page);
            total = (int)page.getTotal();
        } else {
            List<PlanCheckDTO> root = this.mesPlanXiaDaMapper.queryForParentpartid(planCheckDTO, true);
            List<PlanCheckExport> tree = new ArrayList<>();
            for (PlanCheckDTO p:root) {
                List<PlanCheckExport> leaves = this.mesPlanXiaDaMapper.exportCheck(PlanCheckDTO.builder()
                        .jx(CommonUtils.stringNull(p.getJx()))
                        .serialnumber(CommonUtils.stringNull(p.getSerialnumber()))
                        .checkTime2Date(planCheckDTO.getCheckTime2Date())
                        .factoryId(planCheckDTO.getFactoryId())
                        .build(),page);
                for (PlanCheckExport leaf:leaves) {
                    tree.add(leaf);
                }
            }
            total = tree.size();
            int min = (pageNo - 1) * pageSize;
            int max = pageNo * pageSize;
            if (total < max) {
                result = tree.subList(min,total);
            } else {
                result = tree.subList(min,max);
            }
        }
        return new PageData<>(total, result);
    }

    @Override
    public void uploadCheck(List<MesPlanXiaDaDO> list) {
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        MesPlanXiaDaMapper mesPlanXiaDaMapper = sqlSession.getMapper(MesPlanXiaDaMapper.class);
        list.forEach(a -> {
            mesPlanXiaDaMapper.updateById(a);
        });
        sqlSession.commit();
    }

    @Override
    public List<MesOrderTraceTiaoMaVO> mesProgress(PlanCheckDTO planCheckDTO) {
        return this.mesPlanXiaDaMapper.mesProgress(planCheckDTO);
    }
}
